参数 | 类型 | 参数说明 |
---|---|---|
productId | string | 产品id |
deviceId | string | 设备id |
deviceSecret | string | 设备密钥 |
token由如下参数构成:
名称 | 类型 | 是否必须 | 参数说明 | 参数示例 |
---|---|---|---|---|
version | string | 是 | 参数组版本号,日期格式,如“V5.2” | V5.2 |
res | string | 是 | 访问资源 resource格式为:products/{产品id}/devices/{设备id} | products/102668/devices/10016960 |
et | int | 是 | 访问过期时间 expirationTime,unix时间当一次访问参数中的et时间小于当前时间时,平台会认为访问参数过期从而拒绝该访问 | 1537255523表示:北京时间 2018-09-18 15:25:23 |
method | string | 是 | 签名方法 signatureMethod支持hmacmd5、hmacsha1、hmacsha256 | sha1(代表使用hmacsha1算法) |
sign | string | 是 | 签名结果字符串 signature |
sign = base64(hmac_<method>(base64decode(key), utf-8(StringForSignature)))
公式中,key为创建完设备后的设备id(DeviceSecret),Key参与计算前应先进行base64decode操作。
用于计算签名的字符串 StringForSignature的组成顺序按照参数名称进行字符串排序,以'\n'作为参数分隔,当前版本中按照如下顺序进行排序:et、method、res、version
StringForSignature组成示例如下:
StringForSignature = et + '\n' + method + '\n' + res+ '\n' + version
注意:每个参数均为key=value格式组成,但是仅参数中的value参与计算签名的字符串 StringForSignature的组成,若token参数如下:
et = 1609344000
method = sha1
res = products/102668/devices/10016960
version = 1.0
则用于计算签名的字符串StringForSignature为(按照et、method、res、version的顺序)
StringForSignature = "1609344000" + "\n" + "sha1"+ "\n" + "products/102668/devices/10016960"+ "\n" + "1.0"
计算出sign后,将每个参数均采用key=value的形式表示,并用'&'作为分隔符,示例如下:
version=1.0&res=products/102668/devices/10016960&et=1609344000&method=sha1&sign=Li68K+1QmNZRiGlu76mShigqM1k=
token中key=value的形式的value部分需要经过URL编码,需要进行编码的特殊符号如下:
1 | + | %2B |
---|---|---|
2 | 空格 | %20 |
3 | / | %2F |
4 | ? | %3F |
5 | % | %25 |
6 | # | %23 |
7 | & | %26 |
8 | = | %3D |
编码后,上例中实际传输token为:
version=1.0&res=products%2F102668%2Fdevices%2F10016960&et=1609344000&method=sha1&sign=Li68K%2B1QmNZRiGlu76mShigqM1k%3D
et := fmt.Sprintf("%d", time.Now().Unix()+300)
method := "sha1"
res := fmt.Sprintf("products/%s/devices/%s", proId, devId)
version := time.Now().Format("2006-01-02")
_, token := GenerateSignAndToken(et, method, res, version, apiKey)
func GenerateSignAndToken(et, method, res, version, deviceSecret string) (sign, token string) {
stringForSign := fmt.Sprintf("%s\n%s\n%s\n%s", et, method, res, version)
key, _ := base64.StdEncoding.DecodeString(deviceSecret)
var mac hash.Hash
switch method {
case "md5":
mac = hmac.New(md5.New, key)
case "sha1":
mac = hmac.New(sha1.New, key)
case "sha256":
mac = hmac.New(sha256.New, key)
default:
mac = hmac.New(sha1.New, key)
}
mac.Write([]byte(stringForSign))
sign = base64.StdEncoding.EncodeToString(mac.Sum(nil))
token = fmt.Sprintf("version=%s&res=%s&et=%s&method=%s&sign=%s", url.QueryEscape(version), url.QueryEscape(res), url.QueryEscape(et), url.QueryEscape(method), url.QueryEscape(sign))
return
}